import numpy as np
import copy



class Chess(object):
    def __init__(self,size=4):
        self.playerJustMoved = 1
        self.size = size
        self.player = 3-self.playerJustMoved
        self.board = np.ones([self.size, self.size],dtype=np.int8)
        self.gameover = 0
        self.CHESS_INDEX = np.arange(1,self.size**2+1,1,dtype=np.int8).reshape(self.size,-1)

    def Clone(self):
        """ Create a deep clone of this game state.
        """ 
        st = Chess()
        st.board = copy.deepcopy(self.board)
        st.player = copy.deepcopy(self.player)
        st.gameover = copy.deepcopy(self.gameover)
        st.playerJustMoved = copy.deepcopy(self.playerJustMoved)
        return st

    def checkMove(self,move):
        """检查一个move是否合规
        Args:
            move (list): [i,j]
        Returns:
            list: 如果合规：np.array切片索引 [m1,m2,n1,n2], 如果不合规为 []
        """
        
        i=move[0]-1
        j=move[1]-1
        if i>j:
            return []
        m1 = (i)//self.size
        n1 = (i) % self.size
        m2 = (j)//self.size
        n2 = (j) % self.size
        
        if m1!= m2 and n1!=n2:
            return []

        else :
            m2+=1
            n2+=1
            if np.sum(self.board[m1:m2,n1:n2]) == m2-m1+n2-n1-1:
                return [m1,m2,n1,n2]
            else:
                return []
        
    
    def DoMove(self, move):
        '''
        进行一步操作，输入为一个数组，数组中第一个数是第一个棋子坐标，第二个数是第二个棋子坐标。move[0] <= move[2]
        以4*4为例，坐标值分别为：
        1  2  3  4
        5  6  7  8
        9  10 11 12
        13 14 15 16
        '''
        if self.gameover == 1:
            return
        indexs= self.checkMove(move)
        if len(indexs)==0:
            print("Illegal input : ",move,'\n')
            return
        [m1,m2,n1,n2] = indexs
        self.board[m1:m2,n1:n2] = 0
        
        self.playerJustMoved = self.player
        self.player = 3-self.player
        if np.sum(self.board)== 0:
            self.gameover = 1
            

    def GetMoves(self):
        '''
        获得所有可行操作
        '''
        moves = []
        if np.array_equal(self.board,np.zeros([4,4])):
            return moves
        for i in range(1,self.size*self.size+1):
            for j in range(i, self.size*self.size+1):
                if len(self.checkMove([i,j]))>0:
                    moves.append([i,j])
        return moves

    def GetResult(self, playerjm):
        if playerjm == 1 or playerjm == 2:
            if self.playerJustMoved == playerjm:
                return 0
            else:
                return 1
        else:
            return None

    def __repr__(self):
        return str(self.board*self.CHESS_INDEX) +"\n"
    
if __name__ == '__main__':
    game = Chess(4)
    print(game) #打印开局棋盘
        # 1  2  3  4
        # 5  6  7  8
        # 9  10 11 12
        # 13 14 15 16
    available_moves = game.GetMoves() #获得所有可行的动作
    print(available_moves)
    game.DoMove([2,10]) #进行一步可执行动作
    print(game) #打印棋盘
    game.DoMove([2,3]) #进行一步非法动作
    print(game) #打印棋盘，可以看出程序不会执行动作
    game.DoMove([1,1]) #进行一系列动作
    game.DoMove([4,16])
    game.DoMove([5,13])
    game.DoMove([3,15])
    game.DoMove([14,14])
    
    print(game) #游戏结束
    print(game.gameover) #该值为1代表游戏结束
    print(game.GetResult(2)) #获得玩家2的胜负结果，0为失败，1为胜利
    print(game.GetResult(1)) #获得玩家1的胜负结果，0为失败，1为胜利 